package com.wyman.factory.support;

import com.wyman.BeanException;
import com.wyman.factory.BeanFactory;
import com.wyman.factory.config.BeanDefinition;
import com.wyman.factory.config.BeanPostProcessor;
import com.wyman.factory.config.ConfigurableBeanFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author 李伟民
 * @Description DateTime 2024/11/25 01:43
 */
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements ConfigurableBeanFactory {

    //12.11 因为继承了ConfigurableBeanFactory 所以要实现添加BeanPostProcessor 使用ArrayList存储所有的BeanPostProcessor 后面的注册动作和apply动作都是读写这个列表
    private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();

    //模板设计模式 定义容器中获取bean的逻辑 但不负责逻辑中具体方法实现
    @Override
    public Object getBean(String beanName)  {
        Object bean = getSingleton(beanName);
        if (bean != null) {
            return bean;
        }
        BeanDefinition beanDefinition = getBeanDefinition(beanName);
        try {
            return createBean(beanName, beanDefinition,null);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //获取bean时传递参数 是入口
    @Override
    public Object getBean(String beanName, Object[] args) {
        Object bean = getSingleton(beanName);
        if (bean != null) {
            return bean;
        }
        BeanDefinition beanDefinition = getBeanDefinition(beanName);
        try {
            return createBean(beanName, beanDefinition,args);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public <T> T getBean(String beanName,Class<T> requireType) {
        Object bean = getSingleton(beanName);
        if(bean!=null){
            return (T)bean;
        }
        BeanDefinition beanDefinition = getBeanDefinition(beanName);
        try {
            return (T) createBean(beanName,beanDefinition,null);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeanException;

    //负责实现 真正创建bean
    protected abstract Object createBean(String beanName,BeanDefinition beanDefinition,Object[] args) throws Exception;

    //12.11 新增添加bean处理器的功能
    public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor){
        //增加新bean处理器时 需要先删除之前存在的 同样的处理器 难道是存在同一个处理器对象 添加之后 在容器运行过程中 又修改了 需要重新添加 为了避免原来的处理器发挥作用  存疑 不确定
        this.beanPostProcessors.remove(beanPostProcessor);
        //熙增处理器
        this.beanPostProcessors.add(beanPostProcessor);
    }

    public List<BeanPostProcessor> getBeanPostProcessors(){
        return this.beanPostProcessors;
    }
}
